# decorators.py
import collections
from functools import wraps

import rest_framework.request
from utils.custom_exceptions import QueryParamsErrorException
from utils.tools import auto_adapt_to_methods


def params(required:list[str]=None, optional: list[str]=None):
	if required is None: required = []
	if optional is None: optional = []
	def decorator(view_func):
		@wraps(view_func)
		def wrapper(request: rest_framework.request.Request, *args, **kwargs):
			# 在这里将请求中的参数提取出来，方便视图函数直接访问
			request_params = request.query_params.dict()
			if request.method in ["POST", "PUT"]: request_params.update(request.data.dict())
			for param in required:
				if param not in request_params:
					raise QueryParamsErrorException()
			# 对可选参数进行自定义处理
			# 如果可选参数为key=val形式且请求数据中不携带该参数则设置默认值为val
			for param in optional:
				eindex = param.find("=")
				key, val = param[0:eindex], param[eindex+1:]
				if key not in request_params:
					if eindex != -1:
						request_params[key] = val
					else: request_params[param] = None
					
			# 将提取的参数设置为request对象的属性，以便视图函数直接访问
			# ParamsTuple = collections.namedtuple("ParamsTuple", request_params.keys())
			trans2int = ["option", "type", "limit", "offset", "page", "pageSize"]
			request_params = {
				param: int(value) if param in trans2int and value.isdigit() else value
				for param, value in request_params.items()
			}
			request.params = request_params
			# setattr(request, "params", params_tup)
			return view_func(request, *args, **kwargs)
		return wrapper
	return decorator
